package main

import (
	"crypto/aes"
	_ "crypto/aes"
	_ "database/sql/driver"
	"encoding/base64"
	_ "encoding/base64"
	"encoding/binary"
	_ "encoding/binary"
	"encoding/hex"
	_ "encoding/hex"
	_ "encoding/json"
	"errors"
	_ "errors"
	"fmt"
	"github.com/brocaar/lorawan"
	"strings"
)

type AES128Key [16]byte

func main() {
	//b, _ := hex.DecodeString(str)
	src := "hg=="

	reader := strings.NewReader(src)
	decoder := base64.NewDecoder(base64.StdEncoding, reader)
	buf := make([]byte, reader.Len()/4)
	dst := ""
	for {
		n, err := decoder.Read(buf)
		if n == 0 || err != nil {
			break
		}
		dst += string(buf[:n])
	}
	fmt.Println("解码后的数据为:", hex.EncodeToString(buf[:]) )
	result, _ := EncryptFRMPayload(AES128Key{
		0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,
	},true,lorawan.DevAddr{0x22,0x22,0x22,0x22},9,buf[:])
	fmt.Println(hex.EncodeToString(result))
}
// 这里是分析了chirp
func EncryptFRMPayload(key AES128Key, uplink bool, devAddr lorawan.DevAddr, fCnt uint32, data []byte) ([]byte, error) {
	pLen := len(data)
	if pLen%16 != 0 {
		// append with empty bytes so that len(data) is a multiple of 16
		data = append(data, make([]byte, 16-(pLen%16))...)
		fmt.Println(data)
	}
	block, err := aes.NewCipher(key[:])
	if err != nil {
		return nil, err
	}
	if block.BlockSize() != 16 {
		return nil, errors.New("lorawan: block size of 16 was expected")
	}
	s := make([]byte, 16)
	a := make([]byte, 16)
	a[0] = 0x01
	if !uplink {
		a[5] = 0x01
	}
	b, err := devAddr.MarshalBinary()
	if err != nil {
		return nil, err
	}
	copy(a[6:10], b)
	binary.LittleEndian.PutUint32(a[10:14], uint32(fCnt))

	for i := 0; i < len(data)/16; i++ {
		a[15] = byte(i + 1)
		block.Encrypt(s, a)

		for j := 0; j < len(s); j++ {
			data[i*16+j] = data[i*16+j] ^ s[j]
		}
	}
	return data[0:pLen], nil
}